package jehc.djshi.sys.init;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ForkJoinPool;
import jehc.djshi.common.cache.redis.RedisUtil;
import jehc.djshi.common.constant.CacheConstant;
import jehc.djshi.common.util.JsonUtil;
import jehc.djshi.sys.init.task.InitTask;
import jehc.djshi.sys.model.*;
import jehc.djshi.sys.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * 初始化平台数据至缓存中
 * @author 邓纯杰
 *
 */
@Component
@Slf4j
@Order(0)
public class InitSysData implements CommandLineRunner {
	@Autowired
	RedisUtil redisUtil;
	@Autowired
    XtDataDictionaryService xtDataDictionaryService;
	@Autowired
    XtPathService xtPathService;
	@Autowired
    XtIpFrozenService xtIpFrozenService;
	@Autowired
    XtConstantService xtConstantService;
	@Autowired
    XtAreaRegionService xtAreaRegionService;
	@Override
	public void run(String... args) throws Exception {
		try {
			initXtDataDictionary();
			initXtAreaRegion();
			initForkJoinPool();
		} catch (Exception e) {
			log.error("加载异常：{}",e);
		}
	}

    /**
     * 加载数据字典，平台常量及平台路径到缓存中
     */
	private void initXtDataDictionary(){
    	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    	long millis1 = System.currentTimeMillis();
		Map<String, Object> condition = new HashMap<String, Object>();
		List<XtDataDictionary> XtDataDictionaryList = xtDataDictionaryService.getXtDataDictionaryListAllByCondition(condition);
		long millis2 =  System.currentTimeMillis();
		log.info(sdf.format(new Date())+"--->读取数据字典耗时:"+(millis2-millis1)+"毫秒");
		log.info(sdf.format(new Date())+"--->加载缓存配置开始");
		millis2 =  System.currentTimeMillis();
		redisUtil.hset(CacheConstant.SYSHASH,CacheConstant.XTDATADICTIONARYCACHE, JsonUtil.toFastJson(XtDataDictionaryList));
		log.info(sdf.format(new Date())+"--->将数据存入缓存耗时:"+(millis2-millis1)+"毫秒");
		log.info(sdf.format(new Date())+"--->加载缓存配置结束");

		millis1 = System.currentTimeMillis();
		log.info(sdf.format(new Date())+"--->读取平台路径开始");
		List<XtPath> xtPathList = xtPathService.getXtPathListAllByCondition(condition);
		redisUtil.hset(CacheConstant.SYSHASH,CacheConstant.XTPATHCACHE,JsonUtil.toFastJson(xtPathList));
		millis2 =  System.currentTimeMillis();
		log.info(sdf.format(new Date())+"--->读取平台路径缓存耗时:"+(millis2-millis1)+"毫秒");

		millis1 = System.currentTimeMillis();
		log.info(sdf.format(new Date())+"--->读取IP黑户开始");
		condition = new HashMap<String, Object>();
		condition.put("xt_ip_frozen_status", 2);
		List<XtIpFrozen> xtIpFrozenList = xtIpFrozenService.getXtIpFrozenListAllByCondition(condition);
		redisUtil.hset(CacheConstant.SYSHASH,CacheConstant.XTIPFROZENCACHE,JsonUtil.toFastJson(xtIpFrozenList));
		log.info(sdf.format(new Date())+"--->一共加载了:"+xtIpFrozenList.size()+"条平IP黑户数据");
		log.info(sdf.format(new Date())+"--->读取IP黑户缓存耗时:"+(millis2-millis1)+"毫秒");
		millis1 = System.currentTimeMillis();
		log.info(sdf.format(new Date())+"--->读取平台常量开始");

		condition = new HashMap<String, Object>();
		List<XtConstant> xtConstantList = xtConstantService.getXtConstantListAllByCondition(condition);
		redisUtil.hset(CacheConstant.SYSHASH,CacheConstant.XTCONSTANTCACHE,JsonUtil.toFastJson(xtConstantList));
		millis2 =  System.currentTimeMillis();
		log.info(sdf.format(new Date())+"--->一共加载了:"+xtConstantList.size()+"条平台常量数据");
		log.info(sdf.format(new Date())+"--->读取平台常量缓存耗时:"+(millis2-millis1)+"毫秒");
    }
    
    /**
     * 初始化区域至缓存中
     */
    public void initXtAreaRegion(){
    	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    	long millis1 = System.currentTimeMillis();
		Map<String, Object> condition = new HashMap<String,Object>();
		List<XtAreaRegion> list = xtAreaRegionService.getXtAreaRegionListByCondition(condition);
    	long millis2 =  System.currentTimeMillis();
		log.info(sdf.format(new Date())+"--->读取行政区域实例耗时:"+(millis2-millis1)+"毫秒");
		log.info(sdf.format(new Date())+"--->加载行政区域实例缓存开始");
		redisUtil.hset(CacheConstant.SYSHASH,CacheConstant.XTAREAREGIONCACHE,JsonUtil.toFastJson(list));
		log.info(sdf.format(new Date())+"--->加载行政区域实例缓存结束");
    }

	public void initForkJoinPool(){
		long millis1 = System.currentTimeMillis();
		int size = Runtime.getRuntime().availableProcessors();//获取本系统的有效线程数，设置线程池为有效线程的两倍。
		ForkJoinPool forkJoinPool = new ForkJoinPool(size*2);
		try {
			Map<String, Object> condition = new HashMap<String,Object>();
			condition = new HashMap<String, Object>();
			condition.put("xt_ip_frozen_status", 2);
			List<XtIpFrozen> ipFrozenList = xtIpFrozenService.getXtIpFrozenListAllByCondition(condition);
			InitTask initTask = new InitTask(ipFrozenList,10);
			//方法一 同步
			Integer result = forkJoinPool.invoke(initTask);
//                //线程阻塞，等待所有任务完成
//                forkJoinPool.awaitTermination(forkJoinTimeOut, TimeUnit.SECONDS);


//                //方法二 异步
//                ForkJoinTask forkJoinTask = forkJoinPool.submit(initTask);
//                result = new Integer(forkJoinTask.get());


//                //方法三 异步
//                Future<Integer> futureResult = forkJoinPool.submit(initTask);
//                result = futureResult.get();
			long millis2 =  System.currentTimeMillis();
			log.info("存取黑名单实例耗时:"+(millis2-millis1)+"毫秒");
		}catch (Exception e){
			if(null != forkJoinPool){
				forkJoinPool.shutdown();
			}
		}finally {
			if(null != forkJoinPool){
				forkJoinPool.shutdown();
			}
		}
	}
}
